package message;

import java.io.IOException;

import message.visitor.MessageVisitor;
import network.e2e.FrameWriter;
import stalker.Stalker;

/**
 * Represents a message
 * <p>
 * Visitor pattern
 */

public abstract class Message {
  
  private final Stalker client_;
  private final Stalker destination_;
  
  /**
   * Constructs a message
   * @requires client not null
   * @param client request originator
   */
  public Message(Stalker client, Stalker destination) {
    assert (client != null && destination != null);
    client_ = client;
    destination_ = destination;
  }
  
  public abstract <T> T accept(MessageVisitor<T> visitor);
  
  /**
   * Retrieves the originator of this message
   * @return the originator of this message
   */
  public Stalker getClient() {
    return client_;
  }
  
  /**
   * Retrieves the destination of this message
   * @return the destination of this message
   */
  public Stalker getDestination() {
    return destination_;
  }
  
  @Override
  public abstract String toString();
  
  @Override
  public abstract boolean equals(Object obj);
  
  /**
   * Sends self over the net
   * @requires writer not null
   * @param writer the net
   */
  public abstract void send(FrameWriter writer) throws IOException;
  
}
